home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / rs0422.zip / ROSEZSW / PATHS.C < prev    next >
C/C++ Source or Header  |  1990-08-26  |  10KB  |  303 lines

  1. /*
  2.  * Copyright 1988 by the Radio Amateur Telecommunications Society
  3.  * and Thomas A. Moulton, W2VY
  4.  *
  5.  * This software may only be modified, copied, distributed or
  6.  * executed for non-profit purposes by individuals operating
  7.  * systems in the Amateur Radio Service.  Credit to the
  8.  * author(s) and to the Radio Amateur Telecommunications Society
  9.  * must be made in modules where RATS provided software is used,
  10.  * and in any announcements and documentation.  
  11.  *
  12.  * As a non-profit, research and development organization,  the
  13.  * Radio Amateur Telecommunications Society distributes software
  14.  * in both executable and source forms.  This policy is in place
  15.  * to encourage the development and distribution of OSI-based,
  16.  * networking tools.  In order to protect the interests of the
  17.  * Society and the authors, we have placed some conditions
  18.  * of use on the software.  Other groups are encouraged
  19.  * to place the same or similar guidelines on
  20.  * software they produce.
  21.  *
  22.  * The Radio Amateur Telecommunications Society reserves the right
  23.  * to specify and alter the terms under which software provided by
  24.  * the Society may be used.  This policy is consistent with the 
  25.  * objective of uniform and consistent "Open Systems Interconnections."
  26.  * 
  27.  * All acceptable Amateur Radio related uses of this software
  28.  * will be outlined in the "ROSE Implementer's Guide".  Individuals
  29.  * or organizations wishing to add to, or modify the provisions of
  30.  * the guide to accommodate local or evolutionary requirements
  31.  * should document the proposed change(s) and forward them to the
  32.  * Society.  If accepted, written notification will be provided by
  33.  * the Society to the submitting organization or individual(s).
  34.  * The Society will then issue a "ROSE Implementer's Guide Change
  35.  * Notice".  Periodically, the Society will re-issue the "ROSE 
  36.  * Implementer's Guide" and incorporate the text of the change 
  37.  * notices.  This procedure has been put in to place to ensure
  38.  * compatibility between systems and to ensure their "Openness"
  39.  * and interoperability.
  40.  *
  41.  * No part of this software may be used in other packages 
  42.  * without prior authorization from the author or the Society.  
  43.  * Software incorporating this module, all or in part, must be 
  44.  * provided to the Society prior to distribution or use by
  45.  * anyone not directly involved in testing of the revised  
  46.  * environment.  Current releases of the combined software must
  47.  * be provided to the Society in both source and executable
  48.  * forms.  Adequate documention to produce an executable module 
  49.  * from the provided source must also be included.
  50.  *
  51.  * Non-Amateur Radio non-profit uses may be authorized on a case
  52.  * by case basis.  Inquiries for such use may be made in writing
  53.  * to the Society. Non-commercial uses consistent with the
  54.  * general principles of Open Systems Interconnection Reference
  55.  * Model will be generally considered with favor.
  56.  *
  57.  * Commercial licensing of the software is also available based
  58.  * on normal commercial terms.  Licensing inquiries should be
  59.  * directed to the Society.  Commercial licensing of the standard
  60.  * software will be done in situations which materially benefit
  61.  * the Amateur Radio Packet Network.  Additional licensing is
  62.  * reserved by the individual authors.
  63.  * 
  64.  * The Radio Amateur Telecommunications Society provides this software
  65.  * on an "as is" basis.  The Society assumes no liability for
  66.  * loss incurred through the use of this software.  Amateur Radio
  67.  * use of this software implies non-commercial and voluntary 
  68.  * development, deployment and use of this software in a "Amateur",
  69.  * non-commercial service.  Commercial users are encouraged to
  70.  * inspect their copies of the source code.  Source code modification
  71.  * licenses are available if a combined Object and Source Code
  72.  * license was not originally established.
  73.  * 
  74.  * The Society may be contacted by writing or calling at:
  75.  * 
  76.  * The Radio Amateur Telecommunications Society 
  77.  * 206 North Vivyen Street.
  78.  * Bergenfield, New Jersey 07621
  79.  *
  80.  * Telephone: 201-387-8896
  81.  *
  82.  */
  83.  
  84. #include "data.h"
  85. #include "buffer.h"
  86. #include "ax25.h"
  87. #include "ax25l2.h"
  88. #include "l3struc.h"
  89. #include "x25cause.h"
  90.  
  91. #include "l3calls.h"
  92. extern int L3TRIED[];
  93. struct axcb *linked_to(), *NET_CONN();
  94.  
  95. /* This file has the routins that are used by Call Setup to find
  96.    a path for the user's call request. THEY ARE ONLY USED FOR NETWORK LINKS!
  97.  
  98. The only static data structure is a pointer to the pending call list,
  99. everything else is stored in the VCS struc for the pending call.
  100.  
  101. VCS->next    Next vcs in pending chain
  102. VCS->peer    The vcs that caused the call (the calling vc)
  103. VCS->tx_queue    char pointer to the routing table entry
  104. VCS->alt    Used as index into routing alternatives
  105.  
  106.    A link will be tried if the L3TRIED[] entry is zero
  107.  
  108.    When a node link comes up the pending calls will be checked
  109.    to see if it can satisfy the call and it is a higher priority
  110.    than the alternative that the call is currently waiting on
  111.  
  112. The peer (VCS->peer) is fully linked and totally valid, and should
  113. be in P3
  114. */
  115.  
  116. struct VCS *pending_calls;
  117.  
  118. find_path(vc)
  119. register struct VCS *vc;
  120. {        /*     Input a VC in pending call format
  121.                     but ONLY pointed to by it's peer!
  122.             Output    TRUE - call routed, or put back in queue
  123.                 FALSE - Failed, check vc->alt    
  124.                     If alt = 255 then no more routes
  125.                     else no free memory for the link */
  126.  
  127.     static char i, j;
  128.     static unsigned char *altlist;
  129.     static struct axcb *axcb;
  130.  
  131.     if (vc->alt == 255) j = 0;    /* First Time */
  132.     else /* Try next link */ {
  133.         j = vc->alt & 0x0f;    /* Alt recs and L3CALL Network links */
  134.         vc->alt = 255;        /* only range from 0-15 */
  135.     }
  136.     altlist = (unsigned char *)vc->tx_queue;
  137.     while (j < (altlist[0]>>4) & 0x0f) {
  138.         i = altlist[++j];
  139.         if ((i == 0) || (i > 15)) break;    /* Wierd entry */
  140.         if (! L3TRIED[i] ) /* Hasn't been tried in a while */ {
  141.             vc->alt = j;
  142.             if (linked_to(&L3CALL[i],&L3CALL[0],&axcb)) /*Link exists*/ {
  143.                 if (axcb->R == R1) /* Link Ready!! */ {
  144.                     vc->parent = axcb;
  145.                     vc->tx_queue=NULL;
  146.                     vc->WI = L3_WI[i];
  147.                     set_p(vc,P2,0);
  148.                     return TRUE;
  149.                 }
  150.                 else /*  Link Not ready */ {
  151.                     vc->next=pending_calls;
  152.                     pending_calls=vc; /* Wait for R1 */
  153.                     return TRUE;
  154.                 }
  155.             }
  156.             else /* Link does not exist */ {
  157.                 if (!(axcb=NET_CONN(i))) return FALSE;
  158.                 axcb->link_num=i;
  159.                 vc->next=pending_calls;
  160.                 pending_calls=vc; /* Wait for R1 */
  161.                 return TRUE;
  162.             }
  163.         }
  164.     }
  165.     return FALSE;
  166. }
  167.  
  168. route_fail(sx) /* Attempt next alternative for pending calls waiting for path */
  169. char sx;        /* This is ONLY called from l3_st_up, disconnected */
  170. {
  171.     register struct VCS *vc;
  172.     static struct VCS *vc1;
  173.     static unsigned int cause;
  174.     static unsigned char s;
  175.  
  176.     if (!(s=sx)) return; /* Not a network link */
  177.     vc=pending_calls;
  178.     if (!vc) /* No pending calls */ return;
  179.     pending_calls=vc->next;
  180.     vc->next=NULL;
  181.     vc1=NULL;
  182.     while (vc) /* More calls to process */ {
  183.         if (s == *((char *) vc->tx_queue + vc->alt)) {
  184.                  /* Failed with calls pending */
  185.             L3TRIED[s]=L3DELAY[s];
  186.             if (!find_path(vc)) /* Failed, Why? */ {
  187.                 if (vc->alt == 255)/* No alternatives left */ {
  188.                     cause=Out_of_Order;
  189.                 }
  190.                 else  /* No memory */ {
  191.                     cause=Congestion+120;
  192.                 }
  193.                 vc_clear(vc, cause);
  194.             }
  195.             else { /* Find_Path put it back on list,*/
  196.                 /* no longer working on root */
  197.                 /* Or the call is now in P2 */
  198.                 if ( !vc1 && (vc == pending_calls) ) vc1=vc;
  199.             }
  200.         }
  201.         else /* Not working on this link */ {
  202.             vc->next=pending_calls; /* Re-queue this guy */
  203.             pending_calls=vc;
  204.             if (!vc1) /* Is null, was working on root */ vc1=vc;
  205.         }
  206.         if (vc1) /* Not working on the root of the list */ {
  207.             vc=vc1->next;
  208.             if (vc) /* Insure it's not NULL */ {
  209.                 vc1->next=vc->next;
  210.                 vc->next=NULL;
  211.             }
  212.         }
  213.         else /* Need to extract the first item */ {
  214.             vc=pending_calls;
  215.             if (vc) /* Not NULL */ {
  216.                 pending_calls=vc->next;
  217.                 vc->next=NULL;
  218.             }
  219.         }
  220.     }
  221.     return;
  222. }
  223.  
  224. route_success(lnk) /* Process calls that can use the link that is now in R1 */
  225. struct axcb *lnk; /* Will process all calls that have tried or are trying */
  226. {            /* This link */
  227.     register struct VCS *vc;
  228.     static struct VCS *vc1;
  229.     static unsigned char i,s;
  230.  
  231.     if (!(s=lnk->link_num)) return; /* Not a network link */
  232.     /* find_call(&lnk->path[0]); /* First call is destination */
  233.     /* if (s<1 || s>15) return; /* Not a network link */
  234.     L3TRIED[s] = 0;            /* Link is up, allow calls */
  235.     lnk->maxvc = L3_MAXVC[s];
  236.     vc=pending_calls;
  237.     vc1=NULL;
  238.     while (vc) /* More calls to check */ {
  239.         for (i=1; i <= vc->alt; i++) {
  240.             if (s == *(( (char *) vc->tx_queue) + i)) {
  241.                 /* vc's link is finally in R1 !! */
  242.                 if (vc1==NULL) /* Remove first vc */
  243.                     pending_calls=vc->next;
  244.                 else /* have others before me */
  245.                     vc1->next=vc->next;
  246.                 vc->next=NULL;
  247.                 vc->tx_queue=NULL;
  248.                 vc->parent=lnk;
  249.                 vc->WI = L3_WI[s];
  250.                 set_p(vc,P2,0);
  251.                 i=0; /* We removed vc, vc1 is ok */
  252.                 break; /* Exit the for loop */
  253.             }
  254.         } /* End of the for loop */
  255.         if (i) /* the entry was not removed, advance vc1 */
  256.             if (vc1) /* Not Null */        vc1=vc1->next;
  257.             else /* Was working on root */    vc1=pending_calls;
  258.         if (vc1) /* There is a previous pending call */ vc=vc1->next;
  259.         else /* Still working on root */ vc=pending_calls;
  260.     } /* End of While loop */
  261. }
  262.  
  263. extern unsigned char RTable[];
  264. extern unsigned char NPAroute[][16];
  265.  
  266. int check_x121();
  267.  
  268. find_route(ptr,x121)
  269. unsigned char **ptr;
  270. unsigned char x121[];
  271. {
  272.     static unsigned char i, lensv;
  273.     static int l, r, disp;
  274.     register unsigned char *ch;
  275.  
  276.     ch = RTable;        /* Routing Table Root */
  277.     lensv = x121[0] & 0x0f;
  278.  
  279.     i = 0;            /* Start with first digit of DNIC */
  280.     r = -1;
  281.     do {
  282.         if (*ch != 0) r = *(ch+1);
  283.         if (*ch == 2) /* Modify Address and return */ {
  284.             adr_copy(0,NPAroute[r],0, x121); /* New Called */
  285.             return -1;    /* need to re-route call */
  286.         }
  287.  
  288.         if (i == lensv) break;
  289.         l = x121[ (i>>1) +1 ];
  290.         if (!(i&1)) /* High */ l = l>>4;
  291.         i++;
  292.         disp = *(ch+2+(l&0x0f));
  293.         ch += (disp*12);    /* Advance to next record */
  294.     } while (disp != 0);
  295.  
  296.     if (r == -1) return 0;    /* No known route */
  297.     *ptr = &NPAroute[r][0];
  298.     return 1;
  299. }
  300.  
  301.  
  302.  
  303.